# @date: 2023/10/9 15:24
# @author: ls
# @describe: 虹软人脸

from arcface import lib_func
from arcface.engine import ArcFace, ASF_FACE_DETECT, ASF_FACERECOGNITION, ASF_AGE, ASF_GENDER, ASF_DETECT_MODE_IMAGE, MOK
from arcface.struct_info import ASF_SingleFaceInfo, ASF_FaceFeature, ASF_OrientCode


def arc_online_activation(app_key, sdk_key):
    """
    在线激活sdk
    :return:
    """
    return lib_func.ASFOnlineActivation(app_key, sdk_key)


def init_engine():
    """
    初始化人脸引擎
    :return:
    """
    # 获取人脸识别引擎
    face_engine = ArcFace()
    # 需要引擎开启的功能
    mask = ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_AGE | ASF_GENDER
    # 初始化接口
    res = face_engine.ASFInitEngine(ASF_DETECT_MODE_IMAGE, ASF_OrientCode.ASF_OC_0.value, 30, 20, mask)
    return res, face_engine


def uninit_face_engine(face_engine):
    """
    释放引擎
    :param face_engine:
    :return:
    """
    face_engine.ASFUninitEngine()


def detect_face(face_engine, img_cv):
    """
    人脸检测
    :param face_engine:
    :param img_cv:
    :return:
    """
    res, faces = face_engine.ASFDetectFaces(img_cv)
    result_list = []
    if res == MOK:
        for i in range(faces.faceNum):
            single_detected_face1 = ASF_SingleFaceInfo()
            single_detected_face1.faceRect = faces.faceRect[i]
            single_detected_face1.faceOrient = faces.faceOrient[i]

            result_list.append(single_detected_face1)
    return res, faces, result_list


def get_face_feature(face_engine, img_cv, single_detected_face):
    """
    返回人脸特征值对象，用于人脸对比
    :param face_engine:
    :param img_cv:
    :param single_detected_face:
    :return:
    """
    return face_engine.ASFFaceFeatureExtract(img_cv, single_detected_face)


def identify(face_engine, face_feature1, face_feature2):
    """
    人脸对比
    :param face_engine:
    :param face_feature1:
    :param face_feature2:
    :return:
    """
    return face_engine.ASFFaceFeatureCompare(face_feature1, face_feature2)


def face_mask(face_engine, img_cv, face):
    """
    RGB图像属性检测
    :param face_engine:
    :param img_cv:
    :param face:
    :return:
    """
    result = {'age_list': [],
              'gender_list': []}
    processMask = ASF_AGE | ASF_GENDER
    res = face_engine.ASFProcess(img_cv, face, processMask)

    if res == MOK:
        # 获取年龄
        res, ageInfo = face_engine.ASFGetAge()
        if res != MOK:
            print(f'获取年龄属性失败,错误码:{res}')
        else:
            result['age_list'] = ageInfo.ageArray

        # 获取性别
        res, genderInfo = face_engine.ASFGetGender()
        if res != MOK:
            print(f'获取性别属性失败,错误码:{res}')
        else:
            result['gender_list'] = genderInfo.genderArray
    else:
        print(f'人脸属性检测初始化失败,错误码:{res}')

    return res, result


def build_feature_obj(feature):
    """
    构建人脸对比特征值对象
    :param feature:
    :return:
    """
    new_feature1 = ASF_FaceFeature()
    new_feature1.featureSize = len(feature)
    new_feature1.feature = lib_func.malloc(len(feature))
    lib_func.memcpy(new_feature1.feature, feature, len(feature))

    return new_feature1
